package com.ultron.app.util;

import com.ultron.app.exception.ServiceException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import okhttp3.*;
import okio.BufferedSource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 标题：OkHttpClientUtils
 * 说明：
 * 时间：2024/9/25
 * 作者：admin
 */
public class OkHttpClientUtils {
    private OkHttpClient okHttpClient;


    public OkHttpClientUtils() {
        this.okHttpClient = new OkHttpClient().newBuilder().readTimeout(30, TimeUnit.SECONDS).build();

    }
    public OkHttpClientUtils(Long readTimeout) {
        this.okHttpClient = new OkHttpClient().newBuilder().readTimeout(readTimeout, TimeUnit.SECONDS).build();

    }





    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ApiModel("请求头")
    public static class Header {

        @ApiModelProperty(value = "key")
        private String key;

        @ApiModelProperty(value = "key")
        private String value;
    }

    /**
     * 默认get请求
     * @param url
     * @return
     * @throws IOException
     */
    public String get(String url){
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = null;
        try {
            response = this.okHttpClient.newCall(request).execute();
            return response.body().string();
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }

    }


    /**
     * 自定义 POST
     * @param url 请求链接
     * @param bodyRawJson body参数
     * @param mediaTypeStr 媒体类型，取自org.springframework.http.MediaType
     * @param isStream 是否流式请求
     * @param headers 自定义请求头，取自org.springframework.http.HttpHeaders
     * @return
     * @throws IOException
     */
    public String post(String url,String bodyRawJson,String mediaTypeStr,boolean isStream,Header... headers){
        String rsp = this.call(url,HttpMethod.POST,bodyRawJson,mediaTypeStr,isStream,headers);
        return rsp;
    }


    /**
     * 自定义 PUT
     * @param url 请求链接
     * @param bodyRawJson body参数
     * @param mediaTypeStr 媒体类型，取自org.springframework.http.MediaType
     * @param isStream 是否流式请求
     * @param headers 自定义请求头，取自org.springframework.http.HttpHeaders
     * @return
     * @throws IOException
     */
    public String put(String url,String bodyRawJson,String mediaTypeStr,boolean isStream,Header... headers){
        String rsp = this.call(url,HttpMethod.PUT,bodyRawJson,mediaTypeStr,isStream,headers);
        return rsp;
    }

    /**
     * 自定义 DELETE
     * @param url 请求链接
     * @param bodyRawJson body参数
     * @param mediaTypeStr 媒体类型，取自org.springframework.http.MediaType
     * @param isStream 是否流式请求
     * @param headers 自定义请求头，取自org.springframework.http.HttpHeaders
     * @return
     * @throws IOException
     */
    public String delete(String url,String bodyRawJson,String mediaTypeStr,boolean isStream,Header... headers){
        String rsp = this.call(url,HttpMethod.DELETE,bodyRawJson,mediaTypeStr,isStream,headers);
        return rsp;
    }


    /**
     * 自定义 post
     * @param url 请求链接
     * @param httpMethod 请求方法
     * @param bodyRawJson body参数
     * @param mediaTypeStr 媒体类型，取自MediaType
     * @param isStream 是否流式请求
     * @param headers 自定义请求头，取自HttpHeaders
     * @return
     * @throws IOException
     */
    public String call(String url,HttpMethod httpMethod,String bodyRawJson,String mediaTypeStr,boolean isStream,Header... headers){
        String rsp = null;
        MediaType mediaType;
        RequestBody body;
        mediaType = MediaType.parse(StringUtils.isNotBlank(mediaTypeStr)?
                mediaTypeStr : org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE);
        body = RequestBody.create(mediaType,StringUtils.isNotBlank(bodyRawJson)? bodyRawJson:"");
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .method(httpMethod.toString(), body);
        if(null != headers && headers.length >0){
            for(Header header:headers){
                requestBuilder.addHeader(header.key,header.value);
            }
        }
        Request request = requestBuilder.build();
        try {
            Response response = this.okHttpClient.newCall(request).execute();
            if(isStream){
                BufferedSource source = response.body().source();
                rsp = source.readUtf8();
            }else {
                rsp = response.body().string();
            }

            if (!response.isSuccessful()){
                throw new ServiceException("Unexpected code：" +response.code()+"; "+rsp);
            };

        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
        return rsp;
    }

}
